package com.xxl.job.admin.core.complete;

import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.admin.core.model.XxlJobRegistry;
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.core.util.UseAPI;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobContext;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;

/**
 * @author xuxueli 2020-10-30 20:43:10
 */
public class XxlJobCompleter {
    private static Logger logger = LoggerFactory.getLogger(XxlJobCompleter.class);
    public static UseAPI useAPI = new UseAPI();

    /**
     * common fresh handle entrance (limit only once)
     *
     * @param xxlJobLog
     * @return
     */
    public static int updateHandleInfoAndFinish(XxlJobLog xxlJobLog) throws InterruptedException, SQLException, ClassNotFoundException {
        int groupid = xxlJobLog.getJobGroup();
        int jobid = xxlJobLog.getJobId();
        String ip = xxlJobLog.getExecutorAddress();
        XxlJobInfo jobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(jobid);
        XxlJobGroup jobGroup = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().load(groupid);

        //资源释放


        int realgroupid = jobGroup.getId();
        //System.out.println("handdle:" + jobGroup.getId());
        System.out.println(xxlJobLog.getHandleCode());
        //System.out.println(jobInfo.getId());

        //sourceRelease
//        String SourceType = jobInfo.getSourceType();
//        String CPU = jobInfo.getCpu();
//        String Memory = jobInfo.getMemory();
//        int[] task = new int[5];
//        if (SourceType.indexOf("FPGA")!=-1) task[0] = 1;
//        if (SourceType.indexOf("GPU")!=-1) task[1] = 1;
//        if (SourceType.indexOf("NPU")!=-1) task[2] = 1;
//
//        int cpu = Integer.parseInt(CPU);
//        int memory = Integer.parseInt(Memory);
//
//        task[3] = cpu;
//        task[4] = memory;
//
//        int[] temp = new int[5];
//        temp[0] = jobGroup.getFPGA();
//        temp[1] = jobGroup.getGPU();
//        temp[2] = jobGroup.getNPU();
//        temp[3] = jobGroup.getCPU();
//        temp[4] = jobGroup.getMemory();
//
//        for (int j = 0; j < temp.length; j++) {
//            temp[j] += task[j];
//        }
//        jobGroup.setFPGA(temp[0]);
//        jobGroup.setGPU(temp[1]);
//        jobGroup.setNPU(temp[2]);
//        jobGroup.setCPU(temp[3]);
//        jobGroup.setMemory(temp[4]);
        /*
        11.10改版
         */
        XxlJobRegistry xxlJobRegistry = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().loadByName(jobGroup.getAppname());
        jobGroup.setFPGA(xxlJobRegistry.getFPGA());
        jobGroup.setGPU(xxlJobRegistry.getGPU());
        jobGroup.setNPU(xxlJobRegistry.getNPU());
        jobGroup.setCPU(xxlJobRegistry.getCPU());
        jobGroup.setMemory(xxlJobRegistry.getMemory());
        XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(jobGroup);
        System.out.println("任务资源释放");

//        Date date = new Date();
//        System.out.println(DateUtil.formatDateTime(new Date()));
//        System.out.println("执行任務毫秒"+date.getTime());
//        System.out.println("id" + jobGroup.getId() + "cpu" + jobGroup.getCPU());


        // finish
        finishJob(xxlJobLog);

        //XxlJobRegistry jobRegistry = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().
        if (jobGroup == null){
           return XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateHandleInfo(xxlJobLog);
        }

        System.out.println("执行器"+jobGroup.getId());

        // text最大64kb 避免长度过长
        if (xxlJobLog.getHandleMsg().length() > 15000) {
            xxlJobLog.setHandleMsg( xxlJobLog.getHandleMsg().substring(0, 15000) );
        }



//        if(xxlJobLog.getHandleCode()!=200){
//
//
//            Thread.sleep(5000);
//            JobTriggerPoolHelper.trigger(jobid,TriggerTypeEnum.MANUAL,-1,null,XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(jobid).getExecutorParam(),null);
//        }


        // fresh handle
        return XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateHandleInfo(xxlJobLog);
    }


    /**
     * do somethind to finish job
     */
    private static void finishJob(XxlJobLog xxlJobLog) throws SQLException, ClassNotFoundException, InterruptedException {

        // 1、handle success, to trigger child job
        String triggerChildMsg = null;
        if (XxlJobContext.HANDLE_CODE_SUCCESS == xxlJobLog.getHandleCode()) {
            XxlJobInfo xxlJobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(xxlJobLog.getJobId());
            if (xxlJobInfo!=null && xxlJobInfo.getChildJobId()!=null && xxlJobInfo.getChildJobId().trim().length()>0) {
                triggerChildMsg = "<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_child_run") +"<<<<<<<<<<< </span><br>";

                String[] childJobIds = xxlJobInfo.getChildJobId().split(",");
                for (int i = 0; i < childJobIds.length; i++) {
                    int childJobId = (childJobIds[i]!=null && childJobIds[i].trim().length()>0 && isNumeric(childJobIds[i]))?Integer.valueOf(childJobIds[i]):-1;
                    int temp = 0;
                    ArrayList<Integer> ParentId = useAPI.getParentJob(childJobId);
                    for(int j=0;j<ParentId.size();j++){
//                        while(useAPI.getFreeJob(ParentId.get(j))==1){
//                            temp = 0;
//                            System.out.println("执行中");
//                            Thread.sleep(5000);
//                        }

                    if(useAPI.getNewLog(ParentId.get(j))!=-1){
                        XxlJobLog parentLog = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(useAPI.getNewLog(ParentId.get(j)));
                        if(parentLog.getId()==xxlJobLog.getId())
                            parentLog.setHandleCode(xxlJobLog.getHandleCode());
                        //if(useAPI.getFreeJob(ParentId.get(j))==1)
                        if(parentLog.getHandleCode()==0)
                            temp = 1;
                        System.out.println("父"+ParentId.get(j)+":"+parentLog.getId()+"的"+parentLog.getHandleCode());
                    }

                    }
                    //Thread.sleep(2000);
                    if(temp == 0){
                    if (childJobId > 0 ) {

                        JobTriggerPoolHelper.trigger(childJobId, TriggerTypeEnum.PARENT, -1, null, null, null);
                        ReturnT<String> triggerChildResult = ReturnT.SUCCESS;

                        // add msg
                        triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg1"),
                                (i+1),
                                childJobIds.length,
                                childJobIds[i],
                                (triggerChildResult.getCode()==ReturnT.SUCCESS_CODE?I18nUtil.getString("system_success"):I18nUtil.getString("system_fail")),
                                triggerChildResult.getMsg());
                    } else {
                        triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg2"),
                                (i+1),
                                childJobIds.length,
                                childJobIds[i]);
                    }
                    }
                }

            }
        }

        if (triggerChildMsg != null) {
            xxlJobLog.setHandleMsg( xxlJobLog.getHandleMsg() + triggerChildMsg );
        }

        // 2、fix_delay trigger next
        // on the way

    }

    private static boolean isNumeric(String str){
        try {
            int result = Integer.valueOf(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

}
